#include <iostream>
#include <fstream>
#include <iomanip>

#include <sys/types.h>
#include <fcntl.h>

#include "IOError.h"
#include "DigitalIO_DL636F.h"
#include "Counter_DL636G1.h"
#include "TDC_V767.h"

char *devfn="/tmp/sis1100_00remote";

int main(int argc,char *argv[])
{
  cerr << "test_TimeCounter" << endl << endl;

  int crate;
  if( !(crate=open(devfn, O_RDWR, 0)) )
  {
    cerr << "ERROR: could not open \"" << devfn << "\"" << endl;
    exit(1);
  }
  
  vmesysreset(crate);

  DigitalIO_DL636F io(crate,0x8800);
  TDC_V767 tdc(crate,0xaa220000);
  cout << "using tdc @0x" << hex << tdc.getAddress() << dec << endl << endl;

  try {
    io.setO4(0);

    cout << "resetting tdc..." << flush;

    tdc.reset(); sleep(2); cout << "ok" << endl << endl;
    tdc.setMode(TDC_V767::STOP_MATCH);
    tdc.setWindowWidth(100);
    tdc.setWindowOffset(-50);
    tdc.setDataReady();

    int mtime=1000000;
    cout << "measuring " << mtime <<" usec" << endl << endl;
    io.setO1(1);
    usleep(mtime);
    io.setO1(0);

    u_int16_t ec;
    cout << "got " << (ec=tdc.readEventCounter()) << " events" << endl << endl;

    cout << hex
	 << "status1:" << tdc.getStatus1() << endl
	 << "status2:" << tdc.getStatus2() << endl;

    u_int32_t buf_size=100;
    u_int32_t buf[buf_size];
    u_int16_t edc;

    for(int i=0; i < ec; i++) {
      tdc.readEvent(&edc,buf,buf_size);

//      cout << "------------------------------------------------------" << endl;
      int last=0;
      for(int j=0; j<edc; j++) {
	cout << dec << j << ":"
	     << "  channel: " << ((buf[j]&0x7f000000)>>24)
	     << "  start: "  << ((buf[j]&0x00800000)>>23)
	     << "  header: " << ((buf[j]&00600000)>>21)
	     << "  edge: "   << ((buf[j]&00100000)>>20)
	     << "  time measurement: " << (buf[j]&0x0000ffff)
	     << "  delta: " << (buf[j]&0x0000ffff) - last
	     << endl;
	last = (buf[j]&0x0000ffff);
      }
    }

  } catch(IOError ioe) {
    cerr << "catched IOError exception: " << ioe.getMsg() << endl 
	 << "param=0x" << hex << ioe.getParam() << dec << endl << endl;

  }

  close(crate);

  return 0;
}
